package mt.client.gui;

import java.awt.BorderLayout;
import java.awt.FlowLayout;
import java.awt.Font;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.JTextArea;
import javax.swing.JTextField;
import javax.swing.SwingConstants;
import javax.swing.SwingUtilities;

import mt.Order;
import mt.comm.ClientComm;
import mt.dummy.ClientCommDummy;
import mt.dummy.MicroTraderClientDummy;
import mt.ordersList.OrderList;
import mt.ordersList.OrdersManager;

/**
 * Class that represents the graphical user interface for the MicroTrader.
 * 
 * @author Andr� Malvas
 * @author C�sar Alves
 * @author Jorge Martins
 * @author Ricardo Silvestre
 *
 */

public class Gui {

	/**
	 * The ClientComm object that will establish a connection with the server
	 */
	private ClientComm clientComm;

	/**
	 * The manager object that will deal with messages sent from the server and
	 * with the control of the orders
	 */
	private OrdersManager ordersManager;

	/**
	 * Login window
	 */
	private JFrame loginFrame;

	/**
	 * Main window
	 */
	private JFrame mainFrame;

	/**
	 * MyOrders Frame
	 */
	private JFrame myOrdersFrame;

	/**
	 * Public Orders Frame
	 */
	private JFrame publicOrdersFrame;

	private JFrame logFrame;

	/**
	 * Table Model for the MyOrder's list
	 */
	private TableModel myOrdersTableModel;

	/**
	 * Table Model for the Public Order's list
	 */
	private TableModel publicOrdersTableModel;

	/**
	 * JTable for the MyOrder's list. When instanced, it will receive a
	 * TableModel object has an argument
	 */
	private JTable myOrdersTable;

	/**
	 * JTable for the MyOrder's list. When instanced, it will receive a
	 * TableModel object has an argument
	 * 
	 */

	private JTable publicOrdersTable;

	/**
	 * Nickname of the user
	 */
	private String nickname;

	/**
	 * Constructor of the class. Calls the {@link #loginWindow()} to launch the
	 * GUI.
	 * 
	 * @param clientComm
	 *            Parameter to establish a communication with the server
	 */
	public Gui(ClientComm clientComm) {
		this.clientComm = clientComm;

		loginWindow();
	}

	/**
	 * Creates a window where the user should to the login. A warning message
	 * should appear if the user leaves the username textfield in blank
	 * 
	 */
	private void loginWindow() {
		loginFrame = new JFrame();
		loginFrame.setVisible(true);
		loginFrame.setSize(400, 140);
		loginFrame.setLocationRelativeTo(null);
		loginFrame.setResizable(false);
		loginFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		loginFrame.getContentPane().setLayout(null);

		JLabel microTraderLabel = new JLabel("MicroTrader");
		microTraderLabel.setFont(new Font("Arial Black", Font.PLAIN, 13));
		microTraderLabel.setHorizontalAlignment(SwingConstants.CENTER);
		microTraderLabel.setBounds(119, 22, 150, 14);
		loginFrame.getContentPane().add(microTraderLabel);

		JLabel userLabel = new JLabel("Nickname:");
		userLabel.setFont(new Font("Arial Black", Font.PLAIN, 11));
		userLabel.setBounds(35, 58, 78, 14);
		loginFrame.getContentPane().add(userLabel);

		final JTextField textField = new JTextField();
		textField.setBounds(106, 56, 139, 20);
		loginFrame.getContentPane().add(textField);

		JButton connect = new JButton("Connect");
		connect.setBounds(255, 55, 89, 23);
		loginFrame.getContentPane().add(connect);
		connect.addActionListener(new ActionListener() {

			@Override
			public void actionPerformed(ActionEvent e) {
				nickname = textField.getText();
				if(!nickname.equals("")){
					MicroTraderClientDummy microTrader = new MicroTraderClientDummy(
							nickname);
					microTrader.start(clientComm);
					if (clientComm.isConnected()) {
						loginFrame.setVisible(false);
						ordersManager = new OrdersManager(nickname);
						// construct a new table model for "my orders" and add the
						// instance to the ordersManager
						myOrdersTableModel = new TableModel(ordersManager,
								OrderList.Type.MY_ORDER_LIST);
						// construct a new table model for "public orders" and add
						// the instance to the ordersManager
						publicOrdersTableModel = new TableModel(ordersManager,
								OrderList.Type.PUBLIC_ORDER_LIST);
						getAllMessagesFromServer();
						mainFrame();
					}
				}
				else
					JOptionPane.showMessageDialog(null, "The nickname cannot be blanks.");
			}
		});
	}

	/**
	 * Creates the main window of the MicroTrador, where the user has two
	 * buttons to access to his orders and the public orders
	 */
	private void mainFrame() {
		mainFrame = new JFrame("MicroTrader");
		mainFrame.setVisible(true);
		mainFrame.setSize(650, 150);
		mainFrame.setLocationRelativeTo(null);
		mainFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		mainFrame.getContentPane().setLayout(null);

		JButton btnBrowseMyOrders = new JButton("My Orders");
		btnBrowseMyOrders.setBounds(31, 71, 140, 23);
		mainFrame.getContentPane().add(btnBrowseMyOrders);
		btnBrowseMyOrders.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent arg0) {
				myOrdersFrame();
			}
		});

		JButton btnBrowsePublicOrders = new JButton("Public Orders");
		btnBrowsePublicOrders.setBounds(228, 71, 148, 23);
		mainFrame.getContentPane().add(btnBrowsePublicOrders);
		btnBrowsePublicOrders.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent arg0) {
				publicOrdersFrame();
			}
		});

		JButton btnLog = new JButton("Orders History");
		btnLog.setBounds(430, 71, 150, 23);
		mainFrame.getContentPane().add(btnLog);
		btnLog.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent arg0) {
				logFrame();
			}
		});

		JLabel lblMicrotrader = new JLabel("MicroTrader");
		lblMicrotrader.setFont(new Font("Arial Black", Font.PLAIN, 14));
		lblMicrotrader.setBounds(280, 32, 97, 14);
		mainFrame.getContentPane().add(lblMicrotrader);
	}

	/**
	 * Creates a window with the user's orders on it. It also hass three buttons
	 * for selling orders, refresh the orders list, and to return to the main
	 * menu
	 */
	private void myOrdersFrame() {
		mainFrame.setVisible(false);
		myOrdersFrame = new JFrame("My Orders");
		myOrdersFrame.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
		myOrdersFrame.setVisible(true);
		myOrdersFrame.setSize(600, 500);
		myOrdersFrame.setLocationRelativeTo(null);
		myOrdersFrame.setLayout(new BorderLayout());
		JPanel panelNorth = new JPanel();
		myOrdersTable = new JTable(myOrdersTableModel);
		JScrollPane scrollMyOrders = new JScrollPane(myOrdersTable);
		myOrdersTable.setFocusable(false);
		myOrdersTable.setRowSelectionAllowed(false);
		panelNorth.add(scrollMyOrders);
		myOrdersFrame.add(panelNorth, BorderLayout.NORTH);
		JPanel southPanel = new JPanel();
		southPanel.setLayout(new FlowLayout());
		JButton sellButton = new JButton("Sell");
		JButton refreshButton = new JButton("Refresh");
		JButton returnToMenuButton = new JButton("Return to Menu");
		southPanel.add(sellButton);
		southPanel.add(refreshButton);
		southPanel.add(returnToMenuButton);
		myOrdersFrame.add(southPanel, BorderLayout.SOUTH);
		// Ac�›es dos but›es
		// Return to Menu
		returnToMenuButton.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent arg0) {
				myOrdersFrame.setVisible(false);
				mainFrame.setVisible(true);
			}
		});
		// Refresh
		refreshButton.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent arg0) {
				getAllMessagesFromServer();
				myOrdersTableModel.fireTableDataChanged();
			}
		});
		// Sell
		sellButton.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent arg0) {
				sellOrder();
			}
		});
	}

	/**
	 * Creates a window with the public order's on it. It also hass three
	 * buttons for selling orders, refresh the orders list, and to return to the
	 * main menu
	 */
	private void publicOrdersFrame() {
		mainFrame.setVisible(false);
		publicOrdersFrame = new JFrame("Public Orders");
		publicOrdersFrame.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
		publicOrdersFrame.setVisible(true);
		publicOrdersFrame.setSize(600, 500);
		publicOrdersFrame.setLocationRelativeTo(null);
		publicOrdersFrame.setLayout(new BorderLayout());
		JPanel panelNorth = new JPanel();
		publicOrdersTable = new JTable(publicOrdersTableModel);
		JScrollPane scrollPublicOrders = new JScrollPane(publicOrdersTable);
		publicOrdersTable.setFocusable(false);
		publicOrdersTable.setRowSelectionAllowed(false);
		panelNorth.add(scrollPublicOrders);
		publicOrdersFrame.add(panelNorth, BorderLayout.NORTH);
		JPanel southPanel = new JPanel();
		southPanel.setLayout(new FlowLayout());
		JButton buyButton = new JButton("Buy");
		JButton refreshButton = new JButton("Refresh");
		JButton returnToMenuButton = new JButton("Return to Menu");
		southPanel.add(buyButton);
		southPanel.add(refreshButton);
		southPanel.add(returnToMenuButton);
		publicOrdersFrame.add(southPanel, BorderLayout.SOUTH);
		// Ac�›es dos but›es
		// Return to Menu
		returnToMenuButton.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent arg0) {
				publicOrdersFrame.setVisible(false);
				mainFrame.setVisible(true);
			} 
		});
		// Refresh
		refreshButton.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent arg0) {
				getAllMessagesFromServer();
				publicOrdersTableModel.fireTableDataChanged();
			}
		});
		// Buy
		buyButton.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent arg0) {
				buyOrder();
			}
		});
	}

	/**
	 * Method used to create a Sell Order. The User must choose the quantity and price of the selling order.
	 */
	private void sellOrder(){
		String stockToSell = JOptionPane.showInputDialog("Please state the Stock to Sell:");
		if(stockToSell != null){
			if(!stockToSell.equals("")){
				String priceToSell = JOptionPane.showInputDialog("Please state the Price of Sale of " + stockToSell + " :");
				if(priceToSell != null){
					if(!priceToSell.equals("")){
						int priceOfSale = Integer.parseInt(priceToSell);
						if (priceOfSale > 0){
							String quantityToSell = JOptionPane.showInputDialog("Please state the quantity of " + stockToSell + " to Sell:");
							if(quantityToSell != null){
								if(!quantityToSell.equals("")){
									int quantity = Integer.parseInt(quantityToSell);
									if(quantity > 0){
										Order newOrder = Order.createSellOrder(nickname, stockToSell,quantity, priceOfSale);
										ordersManager.getOrdersLog().sentOrder(newOrder);
										clientComm.sendOrder(newOrder);
										getAllMessagesFromServer();
										myOrdersTableModel.fireTableDataChanged();
									}
									else
										JOptionPane.showMessageDialog(null, "The quantity should be above zero.");
								}
								else
									JOptionPane.showMessageDialog(null, "You have to state any quantity to sell");
							}
						}
						else
							JOptionPane.showMessageDialog(null, "The price should be above zero.");
					}
					else
						JOptionPane.showMessageDialog(null, "You have to put a price on the stock.");
				}
			}
			else
				JOptionPane.showMessageDialog(null, "You have to state what stock you want to Sell");
		}
	}


	/**
	 * Method user to create a Buy Order. The user must choose the quantity and
	 * the price of the stock's that he wants to buy.
	 */
	private void buyOrder(){
		String stockToBuy = JOptionPane.showInputDialog("Please state the Stock to Buy:");
		if(stockToBuy != null){
			if(!stockToBuy.equals("")){
				String priceToBuy = JOptionPane.showInputDialog("Please state the Price of Purchase of " + stockToBuy + " :");
				if(priceToBuy != null){
					if(!priceToBuy.equals("")){
						int priceOfPurchase = Integer.parseInt(priceToBuy);
						if (priceOfPurchase > 0){
							String quantityToBuy = JOptionPane.showInputDialog("Please state the quantity of " + stockToBuy + " to Buy:");
							if(quantityToBuy != null){
								if(!quantityToBuy.equals("")){
									int quantity = Integer.parseInt(quantityToBuy);
									if(quantity > 0){
										Order newOrder = Order.createSellOrder(nickname, stockToBuy,quantity, priceOfPurchase);
										ordersManager.getOrdersLog().sentOrder(newOrder);
										clientComm.sendOrder(newOrder);
										getAllMessagesFromServer();
										myOrdersTableModel.fireTableDataChanged();
									}
									else
										JOptionPane.showMessageDialog(null, "The quantity should be above zero.");
								}
								else
									JOptionPane.showMessageDialog(null, "You have to state any quantity to buy.");
							}
						}
						else
							JOptionPane.showMessageDialog(null, "The price should be above zero.");
					}
					else
						JOptionPane.showMessageDialog(null, "You have to put a price on the stock.");
				}
			}
			else
				JOptionPane.showMessageDialog(null, "You have to state what stock you want to Buy");
		}
	}

	/**
	 * Method used to receive messages from the Server.
	 */
	private void getAllMessagesFromServer() {
		while (clientComm.hasNextMessage()) {
			ordersManager.dealWithNewMessage(clientComm.getNextMessage());
		}
	}

	private void logFrame(){
		mainFrame.setVisible(false);
		logFrame = new JFrame("Orders History");
		logFrame.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
		logFrame.setVisible(true);
		logFrame.setSize(600, 500);
		logFrame.setLocationRelativeTo(null);
		logFrame.setLayout(new BorderLayout());
		JPanel panelNorth = new JPanel();
		panelNorth.add(ordersManager.getOrdersLog().getLogTextArea());
		logFrame.add(panelNorth, BorderLayout.NORTH);
		JPanel panelSouth = new JPanel();
		panelSouth.setLayout(new FlowLayout());
		JButton returnToMenuButton = new JButton("Return to Menu");
		panelSouth.add(returnToMenuButton);
		logFrame.add(panelSouth, BorderLayout.SOUTH);
		// Ac�›es dos but›es
		// Return to Menu
		returnToMenuButton.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent arg0) {
				logFrame.setVisible(false);
				mainFrame.setVisible(true);
			} 
		});
	}

}
